import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.util.Vector;

public class Settings {
    
    // List of the available symmetric keys
    public static Vector <Key> symmetric_keys = new Vector <Key> ();
    // List of the available assymetric keys
    public static Vector <Key> assymetric_keys = new Vector <Key> ();
    // Selected key
    public static Key key = null;
    // Indicates if the public or the private key should be used
    public static boolean public_key_selected = true;
    
    public Settings() {
    }
    
    /**
     * Saves the current configuration of the application from the config.ini file
     */
    public static void saveConfiguration() {
        try {
            FileOutputStream f_out = new FileOutputStream("config.ini");
            ObjectOutputStream obj_out = new ObjectOutputStream(f_out);
            if(key == null)
                obj_out.writeObject(new Boolean(false));
            else {
                obj_out.writeObject(new Boolean(true));
                obj_out.writeObject( Settings.key );
            }
            obj_out.writeObject( symmetric_keys );
            obj_out.writeObject( assymetric_keys );
            f_out.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
    /**
     * Loads the current configuration of the application from the config.ini file
     */
    public static void loadConfiguration() {
        if(new File("config.ini").exists()) {
            try {
                FileInputStream f_in = new FileInputStream("config.ini");
                ObjectInputStream obj_in = new ObjectInputStream(f_in);
                Boolean flag = (Boolean) obj_in.readObject();
                if(flag.booleanValue() == true) {
                    Settings.key = (Key) obj_in.readObject();
                    GUI.frame.enableInterface(true);
                }
                symmetric_keys = (Vector <Key>) obj_in.readObject();
                assymetric_keys = (Vector <Key>) obj_in.readObject();
                f_in.close();
            } catch (FileNotFoundException ex) {
                ex.printStackTrace();
            } catch (IOException ex) {
                ex.printStackTrace();
            } catch (ClassNotFoundException ex) {
                ex.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * Adds a key to the application
     * @param Key object
     */
    public static void addKey(Key key) {
        int index;
        
        // If the key is for a symmetric cypher
        if(key.type_key == Key.TypeOfKey.Symmetric) {
            index = getIndexByName(symmetric_keys,key.name);
            if(index == -1)
                Settings.symmetric_keys.add(key);
            else {
                if(key.public_key != null)
                    Settings.symmetric_keys.get(index).public_key = key.public_key;
                if(key.private_key != null)
                    Settings.symmetric_keys.get(index).private_key = key.private_key;
            }
        } else { // If the key is for an assymetric cypher
            index = getIndexByName(assymetric_keys,key.name);
            if(index == -1)
                Settings.assymetric_keys.add(key);
            else {
                if(key.public_key != null)
                    Settings.assymetric_keys.get(index).public_key = key.public_key;
                if(key.private_key != null)
                    Settings.assymetric_keys.get(index).private_key = key.private_key;
            }
        }
    }
    
    /**
     * Gets the index of a key in the keychain by it's name
     * @param keychain The keychain where to search (a vector of keys)
     * @param name The name of the key to search for
     * @return The index where the key is in the specified keychain
     */
    public static int getIndexByName(Vector <Key> keychain, String name) {
        for(int x = 0; x < keychain.size(); x++)
            if(keychain.get(x).name.equals(name))
                return x;
        return -1;
    }
    
    /**
     * Change the name of a key in a certain keychain
     * @param type Type of keychain, to know where to look for the key
     * @param original_name The original name of the key
     * @param new_name The new name of the key
     */
    public static void changeKeyName(String original_name, String new_name) {
        if(new_name.length() == 0)
            return;
        int index;
        if(getIndexByName(Settings.symmetric_keys,new_name) != -1)
            return;
        index = getIndexByName(Settings.symmetric_keys,original_name);
        if(index != -1) {
            Settings.symmetric_keys.get(index).name = new_name;
            return;
        }
        
        if(getIndexByName(Settings.assymetric_keys,new_name) != -1)
            return;
        index = getIndexByName(Settings.assymetric_keys,original_name);
        if(index != -1) {
            Settings.assymetric_keys.get(index).name = new_name;
            return;
        }
    }
}
